package vnreal.ZNEW;

import java.io.File;
import java.io.IOException;

import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;

import org.apache.commons.io.FileUtils;

import vnreal.ZNEW.Algorithms.EA1;
import vnreal.ZNEW.Algorithms.EA2;
import vnreal.ZNEW.Algorithms.EA3;
import vnreal.ZNEW.Algorithms.EA4;
import vnreal.ZNEW.Algorithms.EA_BW;
import vnreal.ZNEW.Xml.Demand;
import vnreal.ZNEW.Xml.HiddenHopDemand;
import vnreal.ZNEW.Xml.Mapping;
import vnreal.ZNEW.Xml.Parameter;
import vnreal.ZNEW.Xml.Resource;
import vnreal.ZNEW.Xml.SLink;
import vnreal.ZNEW.Xml.SLinks;
import vnreal.ZNEW.Xml.SNetwork;
import vnreal.ZNEW.Xml.SNode;
import vnreal.ZNEW.Xml.SNodes;
import vnreal.ZNEW.Xml.Scenario;
import vnreal.ZNEW.Xml.VLink;
import vnreal.ZNEW.Xml.VLinks;
import vnreal.ZNEW.Xml.VNetwork;
import vnreal.ZNEW.Xml.VNode;
import vnreal.ZNEW.Xml.VNodes;
import vnreal.ZNEW.Xml.VirtualNetworks;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomReader;
import com.thoughtworks.xstream.io.xml.DomWriter;

public class XmlTest {

	public static Scenario scenario = new Scenario();
	public static Test test = new Test();
	public static XStream xstream;
	// public static EnergyAlgorithm algorithm;

	private static String data;

	public static void deserialize() {
		test.getScenario();

		xstream = new XStream();
		xstream = modifXML(xstream);
		scenario = (Scenario) xstream.unmarshal(new DomReader(test.doc));
	}

	public static void serialize() {
		xstream.marshal(scenario, new DomWriter(test.doc2));
		try {
			test.setScenario();
		} catch (TransformerException | TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		}
	}

	public static String eA1() {

		// new MyProgressBarDialog(algorithm);
		return EA1.getAlgorithm().saveToFile();
	}

	public static String eABW() {
		return EA_BW.getAlgorithm().saveToFile();
	}

	public static String eA2() {
		// algorithm = new EA2();
		// new MyProgressBarDialog(algorithm);
		return EA2.getAlgorithm().saveToFile();
	}

	public static String eA3() {
		// algorithm = new EA3();
		// new MyProgressBarDialog(algorithm);
		return EA3.getAlgorithm().saveToFile();
	}

	public static String eA4() {
		// algorithm = new EA4();
		// new MyProgressBarDialog(algorithm);
		return EA4.getAlgorithm().saveToFile();
	}

	// public static String eA1_2() {
	// // algorithm = new EA1_2();
	// // new MyProgressBarDialog(algorithm);
	// return new EA1_2().saveToFile();
	// }

	// public static String eA2_2() {
	// // algorithm = new EA2_2();
	// // new MyProgressBarDialog(algorithm);
	// return new EA2_2().saveToFile();
	// }

	// public static String eA3_2() {
	// // algorithm = new EA3_2();
	// // new MyProgressBarDialog(algorithm);
	// return new EA3_2().saveToFile();
	// }

	// public static String eA4_2() {
	// // algorithm = new EA4_2();
	// // new MyProgressBarDialog(algorithm);
	// return new EA4_2().saveToFile();
	// }

	public static void test() {
		data = "";
		data += eA1();
		data += eA2();
		data += eA3();
		data += eA4();
		/*data += eA1_2();
		data += eA2_2();
		data += eA3_2();
		data += eA4_2();*/
		data += eABW();
		// data += eA1_2();
		// data += eA2_2();
		// data += eA3_2();
		// data += eA4_2();
		saveToFile(data);
	}

	private static void saveToFile(String data) {
		try {
			FileUtils.writeStringToFile(new File("test.txt"), data);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static XStream modifXML(XStream xstream) {
		xstream = aliasy(xstream);
		xstream = zamianaList(xstream);
		xstream = atrybuty(xstream);
		return xstream;
	}

	public static XStream aliasy(XStream xstream) {
		xstream.alias("Scenario", Scenario.class);
		xstream.aliasField("SubstrateNetwork", Scenario.class, "SubstrateNetwork");
		xstream.aliasField("VirtualNetworks", Scenario.class, "VirtualNetworks");
		xstream.aliasField("VirtualNetwork", VirtualNetworks.class, "VirtualNetwork");
		xstream.alias("VirtualNetwork", VNetwork.class);
		xstream.alias("Mapping", Mapping.class);
		xstream.aliasField("SubstrateNodes", SNetwork.class, "SubstrateNodes");
		xstream.alias("SubstrateNode", SNode.class);
		xstream.alias("SubstrateLinks", SLinks.class);
		xstream.alias("SubstrateLink", SLink.class);
		xstream.alias("VirtualNodes", VNodes.class);
		xstream.alias("VirtualNode", VNode.class);
		xstream.alias("VirtualLinks", VLinks.class);
		xstream.alias("VirtualLink", VLink.class);
		xstream.alias("Resource", Resource.class);
		xstream.alias("Demand", Demand.class);
		xstream.alias("Parameter", Parameter.class);
		xstream.alias("HiddenHopDemand", HiddenHopDemand.class);

		return xstream;
	}

	public static XStream zamianaList(XStream xstream) {
		xstream.addImplicitCollection(VirtualNetworks.class, "VirtualNetwork");
		xstream.addImplicitCollection(VNodes.class, "VirtualNode");
		xstream.addImplicitCollection(SNodes.class, "SubstrateNode");
		xstream.addImplicitCollection(VLinks.class, "VirtualLink");
		xstream.addImplicitCollection(SLinks.class, "SubstrateLink");
		xstream.addImplicitCollection(VNode.class, "Demand");
		xstream.addImplicitCollection(SNode.class, "Resource");

		xstream.addImplicitCollection(VLink.class, "Demand", "Demand", Demand.class);
		xstream.addImplicitCollection(VLink.class, "HiddenHopDemand", "HiddenHopDemand", HiddenHopDemand.class);
		xstream.addImplicitCollection(SLink.class, "Resource");
		xstream.addImplicitCollection(Demand.class, "Mapping");

		xstream.addImplicitCollection(HiddenHopDemand.class, "Mapping");

		return xstream;
	}

	public static XStream atrybuty(XStream xstream) {
		xstream.useAttributeFor("id", String.class);
		xstream.useAttributeFor("coordinateX", String.class);
		xstream.useAttributeFor("coordinateY", String.class);
		xstream.useAttributeFor("type", String.class);
		xstream.useAttributeFor("value", String.class);
		xstream.useAttributeFor("name", String.class);
		xstream.useAttributeFor("id", String.class);
		xstream.useAttributeFor("source", String.class);
		xstream.useAttributeFor("destination", String.class);
		xstream.useAttributeFor("substrateEntity", String.class);
		xstream.useAttributeFor("resourceType", String.class);
		xstream.useAttributeFor("layer", String.class);
		return xstream;
	}
}